import ShpConverterText from '../shpconverter-text'
// Read GeoJSON Features or geometry objects from a file
function GeoJSONReader(reader) {
  // Read objects synchronously, with callback
  this.readObjects = function(onObject) {
    const bytesToSearch = 5000
    const start = reader.findString('"features"', bytesToSearch) ||
        reader.findString('"geometries"', bytesToSearch)
    const offset = start ? start.offset : 0
    readObjects(offset, onObject)
  }
  this.readObject = readObject

  function readObjects(start, cb) {
    let obj = readObject(start)
    while (obj) {
      cb(JSON.parse(obj.text)) // Use JSON.parse to parse object
      obj = readObject(obj.offset)
    }
  }
  function readObject(offs) {
    const LBRACE = 123
    const RBRACE = 125
    const RBRACK = 93
    const BSLASH = 92
    const DQUOTE = 34
    let level = 0
    let inString = false
    let escapeNext = false
    let buf = reader.readSync(offs)
    let retn = null
    let startPos = null
    let i = null
    let n = null
    let c = null
    for (i=0, n=buf.length; i<n; i++) {
      c = buf[i]
      if (inString) {
        if (escapeNext) {
          escapeNext = false
        } else if (c == DQUOTE) {
          inString = false
        } else if (c == BSLASH) {
          escapeNext = true
        }
      } else if (c == DQUOTE) {
        inString = true
      } else if (c == LBRACE) {
        if (level === 0) {
          startPos = i
        }
        level++
      } else if (c == RBRACE) {
        level--
        if (level === 0) {
          retn = {
            text: ShpConverterText.bufferToString(buf, 'utf8', startPos, i + 1),
            offset: offs + i + 1
          }
          break
        } else if (level == -1) {
          break // error -- "}" encountered before "{"
        }
      } else if (c == RBRACK && level === 0) {
        break // end of collection
      }
      if (i == n-1) {
        buf = reader.expandBuffer().readSync(offs)
        n = buf.length
      }
    }
    return retn
  }
}

export default GeoJSONReader